﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL.Interface;
using DAL.Models;
using DAL.ComplexModels;

namespace DAL.Dao
{
    public class ComplaintBagDaoimpl : BaseDao, IComplaintBagDao
    {
        public int ExistNum { 
            get 
            {
                int res = 0;
                using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                {
                    res = context.Complaint.Count();
                }
                return res;
            } 
            private set 
            { 
            }
        }

        public ComplaintBagDaoimpl(bool use_clock = true) : base(use_clock)
        {
            
        }
       

        public Complaint? Find(int id)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                return context.Complaint.Find(id);
        }

        public int GetSenderUserIDByBagID(string bagID)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                return (from i in context.UserInfo
                    from j in context.Complaint
                    where (bagID.Equals(j.BagId)) && i.TrueName.Equals(j.TrueName)
                    select i
                     ).Select(o => o.Id).ToList().FirstOrDefault();

        }

        public int GetSenderUserIDByComplaintID(int complaintID)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                return (from i in context.UserInfo
                    from j in context.Complaint
                    from k in context.Bag
                    where j.Id==complaintID && k.BagId.Equals(j.BagId) && k.SenderName.Equals(i.UserName)
                    select i
                     ).Select(o => o.Id).ToList().FirstOrDefault();
        }


        public int GetGetterUserIDByComplaintID(int complaintID)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                return (from i in context.UserInfo
                    from k in context.Bag
                    from j in context.Complaint
                    where j.Id == complaintID  && k.BagId.Equals(j.BagId)&& k.GetterName.Equals(i.UserName)
                    select  i
                     ).Select(o => o.Id).ToList().FirstOrDefault();
        }

        public bool Update(int id,Complaint newcomplaint)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                lock (clock_obj_update)
                {
                    try
                    {

                        Complaint? complaint = (from i in context.Complaint
                                                where i.Id.Equals(id)
                                                select i).ToList().FirstOrDefault();
                        if (complaint == null)
                        {
                            return false;
                        }



                        //DbEntityEntry<Bag> entry = DbEntity.expressDBEntities.Entry<Bag>(newbag);
                        //3.设置该对象为被修改过
                        //entry.State = EntityState.Unchanged;
                        //4.设置该对象的 uName属性为修改状态，同时 entry.State 被修改为 Modified 状态
                        //bag.Title = newcomplaint.Title;
                        complaint.Info = newcomplaint.Info;
                        //bag.IdCard = newcomplaint.IdCard;
                        //bag.Phone = newcomplaint.Phone;
                        //bag.TrueName = newcomplaint.TrueName;
                        complaint.ReplyInfo = newcomplaint.ReplyInfo;
                        complaint.ReplyTime = newcomplaint.ReplyTime;
                        //bag.UpdateTime = newcomplaint.UpdateTime;

                        //entry.State = EntityState.Modified;
                        //5.关闭EF实体合法性检查（如果创建出来的要修改的数据有的字段没有赋值则关闭实体合法性检查，如果所有字段都赋值了则不用关闭EF实体合法性检查）

                        //DbEntity.expressDBEntities.Configuration.ValidateOnSaveEnabled = false;

                        //6.重新保存到数据库 -- ef 上下文会根据实体对象的状态，根据 entry.State =Modified 的值生成对应的 update sql 语句.

                        context.SaveChanges();

                    }
                    catch (Exception)
                    {

                        return false;
                    }

                    return true;
                }
            }
      
        
        }
        public bool Delete(int id)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                lock (clock_obj_delete)
                {

                    Complaint complaint = context.Complaint.Find(id);
                    if (complaint == null) return false;
                    context.Complaint.Remove(complaint);
                    context.SaveChanges();
                    return true;
                }
            }
              

        }

        public bool Delete(ComplaintBag complaint)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                lock (clock_obj_delete)
                {

                    context.Complaint.Remove((Complaint)complaint);
                    context.SaveChanges();
                    return true;
                }
            }
             

        }

        public (int,IList<ComplaintBag>)GetList(int rows, int page)
        {

            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                var rs = (from i in context.Complaint
                          from j in context.Bag
                          where i.BagId.Equals(j.BagId)
                          orderby i.Id
                          select new ComplaintBag()
                          {
                              Id = i.Id,
                              Title = i.Title,
                              Info = i.Info,
                              Idcard = i.Idcard,
                              Phone = i.Phone,
                              TrueName = i.TrueName,
                              SubmitTime = i.SubmitTime,
                              ReplyInfo = i.ReplyInfo,
                              ReplyTime = i.ReplyTime,
                              BagId = i.BagId,
                              AddTime = j.AddTime,
                              UpdateTime = j.UpdateTime
                          }
                      ).ToList();

                return (GetTotalPages(rs.Count, rows), rs.Skip((page - 1) * rows).Take(rows).ToList());
            }
                
        }

        public  IList<ComplaintBag> GetList(string username, string phone)
        {

            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                return (from i in context.Complaint
                        from j in context.Bag
                        where i.Phone.Equals(phone) && i.BagId.Equals(j.BagId) && (j.GetterName.Equals(username) || j.SenderName.Equals(username))
                        select new ComplaintBag()
                        {
                            Id = i.Id,
                            Title = i.Title,
                            Info = i.Info,
                            Idcard = i.Idcard,
                            Phone = i.Phone,
                            TrueName = i.TrueName,
                            SubmitTime = i.SubmitTime,
                            ReplyInfo = i.ReplyInfo,
                            ReplyTime = i.ReplyTime,
                            BagId = i.BagId,
                            AddTime = j.AddTime,
                            UpdateTime = j.UpdateTime
                        }
                    ).ToList();
            }

        }


        public (int,IList<ComplaintBag>) GetList(string username,string phone,int rows,int page)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                var rs = (from i in context.Complaint
                          from j in context.Bag
                          where i.BagId.Equals(j.BagId) && i.Phone.Equals(phone) && (j.GetterName.Equals(username) || j.SenderName.Equals(username))
                          select new ComplaintBag()
                          {
                              Id = i.Id,
                              Title = i.Title,
                              Info = i.Info,
                              Idcard = i.Idcard,
                              Phone = i.Phone,
                              TrueName = i.TrueName,
                              SubmitTime = i.SubmitTime,
                              ReplyInfo = i.ReplyInfo,
                              ReplyTime = i.ReplyTime,
                              BagId = i.BagId,
                              AddTime = j.AddTime,
                              UpdateTime = j.UpdateTime
                          }
                   ).ToList();



                return (GetTotalPages(rs.Count, rows), rs.Skip((page - 1) * rows).Take(rows).ToList());
            }
              

        }





        public IList<ComplaintBag> GetList()
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))

                return (from i in context.Complaint
                    from j in context.Bag
                    where i .BagId.Equals(j.BagId)
                    orderby i.Id
                    select new ComplaintBag()
                    {
                        Id = i.Id,
                        Title = i.Title,
                        Info = i.Info,
                        Idcard = i.Idcard,
                        Phone = i.Phone,
                        TrueName = i.TrueName,
                        SubmitTime = i.SubmitTime,
                        ReplyInfo = i.ReplyInfo,
                        ReplyTime = i.ReplyTime,
                        BagId = i.BagId,
                        AddTime = j.AddTime,
                        UpdateTime = j.UpdateTime
                    }).ToList();
        }
     

        public bool Add(Complaint complaint)
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            lock (clock_obj_add)
            {
                
                //complaint.Id = GetList().Last().Id;
                context.Complaint.Add(complaint);
                context.SaveChanges();
                return true;
            }
           
        }




    }
}
